package com.jee.ssm.modules.passData.app;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.setting.dialect.Props;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jee.ssm.common.utils.TokenUtils;
import com.jee.ssm.common.utils.UUIDFactory;
import com.jee.ssm.model.*;
import com.jee.ssm.model.json.Tip;
import com.jee.ssm.modules.black.services.BlackService;
import com.jee.ssm.modules.order.services.OrderService;
import com.jee.ssm.modules.passData.services.PassDataService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 过车记录管理 客户端 Controller
 *
 * @author GaoXiang
 * @version 1.0
 */
@Controller
@RequestMapping("/app/passData")
public class AppPassDataController {

    /**
     * 路侧停车场进车（手持机）
     */
    @RequestMapping(value = "/innerCar")
    @ResponseBody
    public Tip innerCar(String parkId, String parkName, String berthId, MultipartFile passImage, String plateNo, String plateColor, String posUserId, String posUserName, String sbCode, long timestamp, String token) {
        Tip p = TokenUtils.verifyToken(timestamp, token);
        String passurl = "";
        if (p.getSuccess()) {
            long nflag = blackService.countByPlate(plateNo);
            if (nflag == 0) {
                //过车图片保存
                if (passImage != null) {
                    passurl = getImgUrl(passImage);
                }
                if (plateNo == null || "".equals(plateNo)) return new Tip(3, "请输入车牌信息");

                //判断此车牌在某个停车场有没有未完成的进车记录
                long finishCount = passDataService.selectByMap(new HashMap(){{
                    put("finishStatus",0);
                    put("plateNo",plateNo);
                    put("parkId",parkId);
                }});
                if(finishCount > 0) return new Tip(5,"已存在进场记录，请核对信息！");

                PassData passData = new PassData(UUIDFactory.getStringId(), parkId, parkName, 0, berthId, plateNo, new Date(), posUserId, posUserName, sbCode, plateColor,0);
                passData.setPassPicPath(passurl);
//                添加过车记录
                addPassData(passData);
//                更改泊位数量
                updateBerth(parkId, 0);
                return new Tip("进场记录保存成功！");
            } else {
                Black black = blackService.queryByPlate(plateNo);
                return new Tip(4, black);
            }
        } else {
            return new Tip(1, "权限认证失败！");
        }
    }

    /**
     * @Description 进场保存记录并同步到服务器
     * @author yanzengbao
     * @date 2019/8/16 下午5:55
     */
    public void addPassData(PassData passData) {
        //设置泊位状态
        Berth berth = new Berth(passData.getBerthId(),passData.getPlateNo(),4);

        Integer vehType = 1;//默认小车
        if (passData.getPlateColor() != null &&  !"".equals(passData.getPlateColor())){
            if (passData.getPlateColor().equals("2")) {
                vehType = 2;//大车
            }
        }
        passData.setVehType(vehType);
        try {
//            更新车位状态(平台)
            updateBerthStatus(berth);
//          保存进车记录(终端)
            passDataService.insert(passData);
//          保存进车记录(平台)
            insertServerPassData(passData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 路侧停车场出车（手持机）
     */
    @RequestMapping("/enterCar")
    @ResponseBody
    public Tip enterCar(String parkId, String parkName, String plateNo, MultipartFile passImage, String posUserId, String sbCode, String posUserName, String plateColor, long timestamp, String token) {
        Tip tip = TokenUtils.verifyToken(timestamp, token);
        if (!tip.getSuccess()) return new Tip(1, "权限认证失败！");
        String passurl = "";
        //过车图片保存
        if (passImage != null) {
            passurl = getImgUrl(passImage);
        }
        if (plateNo == null || "".equals(plateNo)) return new Tip(1, "请输出车牌信息");

//       保存出车记录
        Tip tip1 = addEnterPassData(parkId, parkName, plateNo, 1, posUserId, passurl, sbCode, posUserName, plateColor);

        if (!tip1.getSuccess()) return tip1;
        Order order = (Order) tip1.getData();
        //更改泊位数量
        updateBerth(parkId, 1);
        if (order.getId() != null && !"".equals(order.getId())) {
            return new Tip("出场成功，生成订单！", tip1.getData());
        } else {
            return new Tip(6, "出场成功！免费停车！");
        }
    }

    /**
     * 出场记录
     */
    public Tip addEnterPassData(String parkId,String parkName, String plateNo, Integer direction, String posUserId, String passPicPath,String sbCode,String posUserName,String plateColor){
        //初始化对象
        Order order = new Order();
        Integer vehType = 1;//默认小车

        //判断是否有未完成的进场记录
        long finishCount = passDataService.selectByMap(new HashMap(){{
            put("finishStatus",0);
            put("plateNo",plateNo);
            put("parkId",parkId);
        }});
        if(finishCount <= 0) return new Tip(1,"当前车辆暂未停车！");

        List<PassData> innerDatas = passDataService.queryByPlateNo(new HashMap(){{
            put("plateNo",plateNo);
            put("parkId",parkId);
        }});
        PassData innerData = innerDatas.get(0);

        //出场记录对象
        PassData passData = new PassData(UUIDFactory.getStringId(),parkId,parkName,innerData.getBerthId(),posUserId,posUserName,plateNo,plateColor,vehType,
                direction,new Date(),innerData.getPassTime(),innerData.getId(),passPicPath,1);

        //车位对象（删除车牌号）
        Berth berth = new Berth(innerData.getBerthId(),"",0);

        if (passData.getPlateColor() != null &&  !"".equals(passData.getPlateColor())){
            if (passData.getPlateColor().equals("2")) {
                vehType = 2;//大车
                passData.setVehType(vehType);
            }
        }else{
            passData.setPlateColor(innerData.getPlateColor());
        }
        //判断收费规则是否正常
        Tip tip = orderService.normalBill(passData);
        if(!tip.getSuccess()) return tip;
        if (tip.getData() != null){
            Double money = (Double) tip.getData();
            passData.setShouldPay(money);
        }else {
            passData.setShouldPay(0.0);
        }
        passData.setSbCode(sbCode);
        try {
//            更新进场记录完成状态
            innerData.setFinishStatus(1);
            passDataService.updateById(innerData);
            //更新服务器车位状态
            updateBerthStatus(berth);
//          保存出车记录(终端)
            passDataService.insert(passData);
//          保存出车记录(平台)
            insertServerPassData(passData);

            if(passData.getShouldPay() != 0.0){
                //生成订单
                order = addOrder(passData, sbCode,0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Tip(order);
    }

    /**
     * @param passData
     * @param sbCode
     * @param orderStatus  订单状态（订单状态（0,未支付，1，已支付,2 逃缴））
     * @return
     */
    public Order addOrder(PassData passData,String sbCode,Integer orderStatus){
        double money = 0.00;
        Tip tip = orderService.normalBill(passData);
        if (tip.getSuccess()){
            money = (double) tip.getData();
        }
        long min = (passData.getPassTime().getTime() - passData.getInPassTime().getTime()) / 60000;
        //String time = Long.toString(hour);
        int time2 = (int)min;
        //订单对象
        Order order = new Order(UUIDFactory.getStringId(),UUIDFactory.getStringId(),passData.getParkId(),passData.getParkName(),time2,passData.getInPassTime(),passData.getPassTime(),
                sbCode, passData.getPlateNo(),passData.getPlateColor(),orderStatus,money,passData.getVehType().toString(),passData.getPosUserId());
        try {
            orderService.insert(order);
            //同步订单到平台服务器
            insertServerOrder(order);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return order;
    }

    /**
     * @Description 保存图片返回图片url
     * @author yanzengbao
     * @date 2019/8/16 下午3:17
     */
    private String getImgUrl(MultipartFile passImage){
        String format = DateUtil.format(new Date(), "yyyyMMdd");
        String passPicPath = "";
        String passurl = "";
        try {
            String imgName = passImage.getOriginalFilename();
            passPicPath = "E:\\passingRecord\\images\\" + format + "\\" + imgName;
//            passPicPath = "/home/zsj/img/carPassImage/"+imgName;
//            String picName = UUIDFactory.getStringId() + ".jpg";
            passurl = "/images/" + format + "/" + imgName;
            File file = new File(passPicPath);
            if (!file.getParentFile().exists()) {
                file.mkdirs();
            }
            passImage.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return passurl;
    }

    /**
     * @Description 上传到服务器保存过车记录
     * @author yanzengbao
     * @date 2019/8/16 下午2:29
     */
    private void insertServerPassData(PassData passData){
        try {
            //Map map = new HashMap();
            Props props = new Props("config/project.properties");
            String serverUrl = props.getProperty("server.url");
            String method = props.getProperty("tc.insertPassData");
            String jsonPassData = JSONObject.toJSONString(passData);
            //map.put("jsonPassData",jsonPassData);
            if(passData.getPassPicPath() != null && !"".equals(passData.getPassPicPath())){
                String qz_url = "E:/passingRecord/";
                String realPath = qz_url + passData.getPassPicPath();
                System.out.println("读取图片实际存储路径：：" + realPath);
                File file = new File(realPath);
                HttpRequest.post(serverUrl + method).form("jsonPassData",jsonPassData).form("passImg",file).execute().body();
            }else{
                System.out.println("上传手持机不带图片的过车记录");
                HttpRequest.post(serverUrl + method).form("jsonPassData",jsonPassData).execute().body();
            }
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("服务器未链接！");
        }
    }

    /**
     * @Description 获取停车场信息
     * @author yanzengbao
     * @date 2019/8/16 下午5:54
     */
    private Park getParkInfo(String parkId){
        Park park = new Park();
        Map map = new HashMap();
        try {
            Props props = new Props("config/project.properties");
            String url = (String) props.get("server.url");
            String getBerthdetails = (String) props.get("getParkInfo");
            map.put("parkId", parkId);
            String parkInfo = HttpUtil.post(url + getBerthdetails, map);
            park = JSONObject.parseObject(parkInfo, Park.class);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("服务器未链接！");
        }
        return park;
    }

    /**
     * @Description 修改服务器停车场车位数量
     * @author yanzengbao
     * @date 2019/8/16 下午5:54
     */
    private void updateParkInfo(Park park){
        Map map = new HashMap();
        try {
            Props props = new Props("config/project.properties");
            String url = (String) props.get("server.url");
            String updateByParkId = (String) props.get("tc.updateByParkId");
            String jsonPark = JSONObject.toJSONString(park);
            map.put("jsonPark",jsonPark);
            HttpUtil.post(url + updateByParkId, map);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("服务器未链接！");
        }
    }

    /**
     * @Description 更新服务器车位u状态
     * @author yanzengbao
     * @date 2019/8/16 下午1:58
     */
    private void updateBerthStatus(Berth berth){
        try{
            Props props = new Props("config/project.properties");
            String serverUrl = props.getProperty("server.url");
            String method = props.getProperty("tc.updateByBerthId");
            Map map = new HashMap();
            String jsonBerth = JSONObject.toJSONString(berth);
            map.put("jsonBerth",jsonBerth);
            HttpUtil.post(serverUrl + method, map);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("服务器未链接！");
        }
    }

    /**
     * @Description 同步订单到平台服务器
     * @author yanzengbao
     * @date 2019/8/15 下午3:34
     */
    private void insertServerOrder(Order order){
        try {
            Props props = new Props("config/project.properties");
            String url = props.getProperty("server.url");
            String method = props.getProperty("tc.insertOrder");
            String jsonOrder = JSONObject.toJSONString(order);
            HttpRequest.post(url + method).form("jsonOrder",jsonOrder).execute().body();
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("服务器未链接！");
        }
    }

    /**
     * 更新服务器停车场剩余车位数量
     * @param parkId
     * @param type 0-入，1-出
     */
    public void updateBerth(String parkId, int type) {
        //获取服务器停车场信息
        Park park = getParkInfo(parkId);
        if (park != null) {
            Integer berthNum = park.getBerthSurplus();
            if (type == 0) {
                berthNum = berthNum - 1;
                if (berthNum < 0) {
                    berthNum = 0;
                }
            } else {
                berthNum = berthNum + 1;
                if (berthNum > park.getBerthNum()) {
                    berthNum = park.getBerthNum();
                }
            }
            //设置车位剩余数量
            park.setBerthSurplus(berthNum);
            updateParkInfo(park);
        }
    }


    /**
     * 逃缴
     */
    @RequestMapping(value = "/runAway")
    @ResponseBody
    public Tip runAway(String parkId, String parkName, String plateNo, String posUserId,String sbCode, String posUserName,String plateColor,long timestamp, String token){
        Tip tip = TokenUtils.verifyToken(timestamp,token);
        Order order = new Order();
        if (tip.getSuccess()){
            //进场记录对象
            List<PassData> innerDatas = passDataService.queryByPlateNo(new HashMap(){{
                put("plateNo",plateNo);
                put("parkId",parkId);
            }});
            if(innerDatas == null || innerDatas.isEmpty()) return new Tip(1,"当前车辆暂未停车！");
            PassData innerData = innerDatas.get(0);

            //出场记录对象
            PassData passData = new PassData(UUIDFactory.getStringId(),parkId,parkName,1,innerData.getBerthId(),plateNo,new Date(),posUserId,posUserName,sbCode,plateColor,1);

            int vehType =1;
            if (plateColor != null &&  !"".equals(plateColor)){
                if (plateColor.equals("2")) {
                    vehType = 2;//大车
                }
            }else{
                passData.setPlateColor(innerData.getPlateColor());
            }
            passData.setVehType(vehType);
            passData.setInPassTime(innerData.getPassTime());
            passData.setInUniqueNo(innerData.getId());

            //判断收费规则是否正常
            tip = orderService.normalBill(passData);
            if(!tip.getSuccess()) return tip;

            //车位对象（删除车牌号）
            Berth berth = new Berth(innerData.getBerthId(),"",0);

            if (tip.getData() != null){
                Double money = (Double) tip.getData();
                passData.setShouldPay(money);
            }else {
                passData.setShouldPay(0.0);
            }
            try {
//                更新进场记录完成状态
                innerData.setFinishStatus(1);
                passDataService.updateById(innerData);

//              更新服务器停车场剩余车位数
                updateBerth(parkId,1);
//              更新服务器车位状态
                updateBerthStatus(berth);
//              保存逃缴出车记录(终端)
                passDataService.insert(passData);
//              保存出车记录(平台)
                insertServerPassData(passData);

                if(passData.getShouldPay() != 0.0){
                    //生成订单
                    order = addOrder(passData,sbCode,2);
                    //黑名单
                    Black black = new Black(UUIDFactory.getStringId(),parkId,order.getId(),new Date(),posUserName,posUserId,plateNo,passData.getShouldPay(),parkName,innerData.getId(),
                            innerData.getPassPicPath(),innerData.getPassTime());
                    blackService.insert(black);
                    return new Tip("成功保存逃缴订单！",order);
                }else{
                    return new Tip(6,"出场成功！免费停车！");
                }
            } catch (Exception e) {
                e.printStackTrace();
                return new Tip(1,"false!");
            }
        }else {
            return new Tip(1, "权限认证失败！");
        }
    }


    @RequestMapping(value = "/getBerthdetails")
    @ResponseBody
    public Tip getBerthdetails(String pId){
        PassData passData = passDataService.selectById(pId);
        Tip tip = orderService.normalBill(passData);
        Double money = (Double) tip.getData();
        return new Tip();
    }

    /**
     * @Description 通用验证方法 验证车位是否是空闲状态
     * @author yanzengbao
     * @date 2019/8/12 下午4:56
     */
    private Tip valBerthIsUse(String berthId){
        try {
            Props props = new Props("config/project.properties");
            String serverUrl = props.getProperty("server.url");
            String method = props.getStr("getBerthInfo");
            String result = HttpRequest.get(serverUrl + method).form("berthId",berthId).execute().body();
            Berth berth = JSON.parseObject(result,Berth.class);
            if(berth != null){
                if(berth.getStatus() == 0){
                    return new Tip();
                }else{
                    return new Tip(1,"车位被占用！");
                }
            }else{
                return new Tip(3,"未查到相关车位信息！");
            }
        }catch (Exception e){
            //e.printStackTrace();
            return new Tip(2,"服务器未链接！");
        }
    }


    //---------------------------- property -------------------------------

    @Resource
    private PassDataService passDataService;
    @Resource
    private OrderService orderService;
    @Resource
    private BlackService blackService;

}
